// this file includes RDC, Util, Gui
var RDC = new Rdc();

//
function $(s) {
	var el = document.getElementById(s);
	if (el === null) {
		el = document.getElementsByName(s)[0];
	}
	if (el === null) {
		window.alert("Can't find the object " + s);
	}
	return el;
}

// -------------------------------------------------------------------------------------
// 
function Rdc() {
	this.util = new Util();
	this.gui = new Gui();
	this.image = new UploadImage();
	this.jsconst = new JSConst();
}

// -------------------------------------------------------------------------------------
// this function common constant parameters used in other JS codes
function JSConst() {
	this.DATE_FORMAT_yMd = "yyyy-MM-dd";
	this.DATE_FORMAT_yMdHms = "yyyy-MM-dd HH:mm:ss";
	this.DATE_FORMAT_yMdHm = "yyyy-MM-dd HH:mm";
	this.DATE_FORMAT_Hm = "HH:mm";
}

// -------------------------------------------------------------------------------------
// js class of Util: it contains some common methods
function Util() {
	var PWD_MIN_LENGTH = 6;
	var PWD_MAX_LENGTH = 16;
	var MAIL_MIN_LENGTH = 5;
	
	// count the lenght of the string including Chinese characters
	this.countChars = function (str) {
		if (str === null) {
			return -1;
		}
		/* ignore the DWORD
		var count = 0;
		for (var i = 0; i < str.length; i += 1) {
			count += (str.charCodeAt(i) > 255) ? 2 : 1;
		}
		*/
		return str.length;
	};
	
	// trim the long text and make its length not greater than max
	this.trimText = function (elemId, max) {
		var elm = $(elemId);
		if (typeof elm.innerHTML != "undefined") {
			if (this.countChars(elm.innerHTML) > max) {
				elm.innerHTML = elm.innerHTML.substring(0, max);
			}
		} else {
			if (typeof elm.value != "undefined") {
				if (this.countChars(elm.value) > max) {
					elm.value = elm.value.substring(0, max);
				}
			}
		}
	};
	
	// trim the long text and make its length not greater than max
	this.trimString = function (str, max) {
		if (RDC.util.isString(str)) {
			if (this.countChars(str) > max) {
				str = str.substring(0, max) + "...";
			}
		} 
		return str;
	};
	
	// check if the num is an positive integer
	this.isInteger = function (integ) {
		return isInt(integ);
	};
	function isInt(integ) {
		var rule = /^[0-9]*[0-9][0-9]*$/;
		return rule.test(integ);
	}
	
	// check if it is a number
	this.isNumber = function (num) {
		if (num === null || typeof num == "undefined" || num.length === 0) {
			return false;
		}
		var digits = "1234567890";
		for (var i = 0; i < num.length; i += 1) {
			if (digits.indexOf(num.charAt(i)) == -1) {
				return false;
			}
		}
		return true;
	};
	
	// verify if the string is an integer and it should be not greater than max
	this.verifyInteger = function (num, min, max) {
		if (!this.isNumber(num)) {
			return false;
		} else {
			var n = parseInt(num);
			return (n < min || n > max) ? false : true;
		}
	};
	
	// verify if the mail is valid
	this.verifyMail = function (mail) {
		// a mail consists of at least five characters
		if (mail === null || mail.length < MAIL_MIN_LENGTH) {
			return false;
		}
		var str = "";
		mail = mail.replace(/^\s+|\s+$/g, "");
		for (var i = 0, j = mail.length; i < j; i += 1) {
			var ch = mail.charCodeAt(i);
			if (ch >= 65281 && ch <= 65373) {
				str += String.fromCharCode(ch - 65248);
			} else {
				str += String.fromCharCode(ch);
			}
		}
		var pattern = /^[A-Z_a-z0-9-\.]+@([A-Z_a-z0-9-]+\.)+[a-z0-9A-Z]{2,4}$/;
		return (pattern.test(str));
	};
	
	// remove the blanks at the front and tail of a string
	this.trimSpaces = function (str) {
		return (str !== null) ? str.replace(/(^\s*)|(\s*$)/g, "") : str;
	};
	
	// return: 0 - invalid; 1 - weak; 2 - general; 3 - strong 
	this.verifyPassword = function (pwd) {
		if (pwd === null) {
			return 0;
		} else {
			if (pwd.length < PWD_MIN_LENGTH || pwd.length > PWD_MAX_LENGTH) {
			// check its length
				return 0;
			}
		}
		var ls = 0;
		if (pwd.match(/[a-z]/ig)) {
			ls += 1;
		}
		if (pwd.match(/[0-9]/ig)) {
			ls += 1;
		}
		if (pwd.match(/(.[^a-z0-9])/ig)) {
			ls += 1;
		}
		return ls;
	};
	
	// verify the input text by given min and max length. the blanks at the front and tail won't be counted
	this.verifyText = function (text, min, max) {
		if (text === null || min < 0 || (min > max)) {
			return false;
		} else {
			var len = this.countChars(this.trimSpaces(text));
			return (len < min || len > max) ? false : true;
		}
	};
	
	// NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
	// Examples:
	//  "MMM d, y" matches: January 01, 2000
	//                      Dec 1, 1900
	//                      Nov 20, 00
	//  "M/d/yy"   matches: 01/20/00
	//                      9/2/00
	//  "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
	// ------------------------------------------------------------------
	var MONTH_NAMES = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
	var DAY_NAMES = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
	var _tokens = new Array("yyyy", "yy", "MMM", "MM", "dd", "hh", "h", "mm", "ss", "ampm", "HH", "H", "KK", "K", "kk", "k");
	function LZ(x) {
		return (x < 0 || x > 9 ? "" : "0") + x;
	}
	function isTokenValid(token) {
		for (var i = 0; i < _tokens.length; i += 1) {
			if (_tokens[i] == token) {
				return true;
			}
		}
		return false;
	}

	// ------------------------------------------------------------------
	// isDate ( date_string, format_string )
	// Returns true if date string matches format of format string and
	// is a valid date. Else returns false.
	// It is recommended that you trim whitespace around the value before
	// passing it to this function, as whitespace is NOT ignored!
	// ------------------------------------------------------------------
	this.isValidDate = function (val, format) {
		var date = this.stringToDate(val, format);
		if (date === 0) {
			return false;
		}
		return true;
	};

	// -------------------------------------------------------------------
	// compareTwoDates(date1,date1format,date2,date2format)
	//   Compare two date strings to see which is greater.
	//   Returns:
	//   1 if date1 is greater than date2
	//   0 if date1 is smaller than date2 or if they are the same
	//  -1 if either of the dates is in an invalid format
	// -------------------------------------------------------------------
	this.compareTwoDatesWithFormat = function (date1, dateformat1, date2, dateformat2) {
		var d1 = this.stringToDate(date1, dateformat1);
		var d2 = this.stringToDate(date2, dateformat2);
		if (d1 === 0 || d2 === 0) {
			return -1;
		} else {
			if (d1 > d2) {
				return 1;
			}
		}
		return 0;
	};
	this.compareTwoDates = function (date1, date2) {
		return this.compareTwoDatesWithFormat(date1, RDC.jsconst.DATE_FORMAT_yMd, date2, RDC.jsconst.DATE_FORMAT_yMd);
	};

	// ------------------------------------------------------------------
	// convertDateToString (date_object, format)
	// Returns a date in the output format specified.
	// The format string uses the same abbreviations as in stringToDate()
	// ------------------------------------------------------------------
	this.dateToString = function (date, format) {
		if (date === null || format === null) {
			return null;
		}
		format = format + "";
		var result = "";
		var i_format = 0;
		var c = "";
		var token = "";
		var y = date.getYear() + "";
		var M = date.getMonth() + 1;
		var d = date.getDate();
		var E = date.getDay();
		var H = date.getHours();
		var m = date.getMinutes();
		var s = date.getSeconds();
		// var yyyy, yy, MMM, MM, dd, hh, h, mm, ss, ampm, HH, H, KK, K, kk, k;
		// Convert real date parts into formatted versions
		var value = new Object();
		if (y.length < 4) {
			y = "" + (y - 0 + 1900);
		}
		value["y"] = "" + y;
		value["yyyy"] = y;
		value["yy"] = y.substring(2, 4);
		value["M"] = M;
		value["MM"] = LZ(M);
		value["MMM"] = MONTH_NAMES[M - 1];
		value["NNN"] = MONTH_NAMES[M + 11];
		value["d"] = d;
		value["dd"] = LZ(d);
		value["E"] = DAY_NAMES[E + 7];
		value["EE"] = DAY_NAMES[E];
		value["H"] = H;
		value["HH"] = LZ(H);
		if (H === 0) {
			value["h"] = 12;
		} else {
			if (H > 12) {
				value["h"] = H - 12;
			} else {
				value["h"] = H;
			}
		}
		value["hh"] = LZ(value["h"]);
		if (H > 11) {
			value["K"] = H - 12;
		} else {
			value["K"] = H;
		}
		value["k"] = H + 1;
		value["KK"] = LZ(value["K"]);
		value["kk"] = LZ(value["k"]);
		if (H > 11) {
			value["a"] = "PM";
		} else {
			value["a"] = "AM";
		}
		value["m"] = m;
		value["mm"] = LZ(m);
		value["s"] = s;
		value["ss"] = LZ(s);
		while (i_format < format.length) {
			c = format.charAt(i_format);
			token = "";
			while ((format.charAt(i_format) == c) && (i_format < format.length)) {
				token += format.charAt(i_format);
				i_format += 1;
			}
			if (isTokenValid(token)) {
				result = result + value[token];
			} else {
				result = result + token;
			}
		}
		return result;
	};
	
	// ------------------------------------------------------------------
	// Utility functions for parsing in stringToDate()
	// ------------------------------------------------------------------
	function getInt(str, i, minlength, maxlength) {
		for (var x = maxlength; x >= minlength; x -= 1) {
			var token = str.substring(i, i + x);
			if (token.length < minlength) {
				return null;
			}
			if (isInt(token)) {
				return token;
			}
		}
		return null;
	}

	// ------------------------------------------------------------------
	// stringToDate( date_string , format_string )
	//
	// This function takes a date string and a format string. It matches
	// If the date string matches the format string, it returns the
	// getTime() of the date. If it does not match, it returns 0.
	// ------------------------------------------------------------------
	this.stringToDate = function (val, format) {
		val = val + "";
		format = format + "";
		var i_val = 0;
		var i_format = 0;
		var c = "";
		var token = "";
		// var token2 = "";
		var x, y;
		var now = new Date();
		var year = now.getYear();
		var month = now.getMonth() + 1;
		var date = 1;
		var hh = now.getHours();
		var mm = now.getMinutes();
		var ss = now.getSeconds();
		var ampm = "";
		while (i_format < format.length) {
		// Get next token from format string
			c = format.charAt(i_format);
			token = "";
			while ((format.charAt(i_format) == c) && (i_format < format.length)) {
				token += format.charAt(i_format);
				i_format += 1;
			}
		// Extract contents of value based on format token
			if (token == "yyyy" || token == "yy" || token == "y") {
				if (token == "yyyy") {
					x = 4;
					y = 4;
				} else {
					if (token == "yy") {
						x = 2;
						y = 2;
					} else {
						if (token == "y") {
							x = 2;
							y = 4;
						}
					}
				}
				year = getInt(val, i_val, x, y);
				if (year === null) {
					return 0;
				}
				i_val += year.length;
				if (year.length == 2) {
					if (year > 70) {
						year = 1900 + (year - 0);
					} else {
						year = 2000 + (year - 0);
					}
				}
			} else {
				if (token == "MMM" || token == "NNN") {
					month = 0;
					for (var i = 0; i < MONTH_NAMES.length; i += 1) {
						var month_name = MONTH_NAMES[i];
						if (val.substring(i_val, i_val + month_name.length).toLowerCase() == month_name.toLowerCase()) {
							if (token == "MMM" || (token == "NNN" && i > 11)) {
								month = i + 1;
								if (month > 12) {
									month -= 12;
								}
								i_val += month_name.length;
								break;
							}
						}
					}
					if ((month < 1) || (month > 12)) {
						return 0;
					}
				} else {
					if (token == "EE" || token == "E") {
						for (i = 0; i < DAY_NAMES.length; i += 1) {
							var day_name = DAY_NAMES[i];
							if (val.substring(i_val, i_val + day_name.length).toLowerCase() == day_name.toLowerCase()) {
								i_val += day_name.length;
								break;
							}
						}
					} else {
						if (token == "MM" || token == "M") {
							month = getInt(val, i_val, token.length, 2);
							if (month === null || (month < 1) || (month > 12)) {
								return 0;
							}
							i_val += month.length;
						} else {
							if (token == "dd" || token == "d") {
								date = getInt(val, i_val, token.length, 2);
								if (date === null || (date < 1) || (date > 31)) {
									return 0;
								}
								i_val += date.length;
							} else {
								if (token == "hh" || token == "h") {
									hh = getInt(val, i_val, token.length, 2);
									if (hh === null || (hh < 1) || (hh > 12)) {
										return 0;
									}
									i_val += hh.length;
								} else {
									if (token == "HH" || token == "H") {
										hh = getInt(val, i_val, token.length, 2);
										if (hh === null || (hh < 0) || (hh > 23)) {
											return 0;
										}
										i_val += hh.length;
									} else {
										if (token == "KK" || token == "K") {
											hh = getInt(val, i_val, token.length, 2);
											if (hh === null || (hh < 0) || (hh > 11)) {
												return 0;
											}
											i_val += hh.length;
										} else {
											if (token == "kk" || token == "k") {
												hh = getInt(val, i_val, token.length, 2);
												if (hh === null || (hh < 1) || (hh > 24)) {
													return 0;
												}
												i_val += hh.length;
												hh -= 1;
											} else {
												if (token == "mm" || token == "m") {
													mm = getInt(val, i_val, token.length, 2);
													if (mm === null || (mm < 0) || (mm > 59)) {
														return 0;
													}
													i_val += mm.length;
												} else {
													if (token == "ss" || token == "s") {
														ss = getInt(val, i_val, token.length, 2);
														if (ss === null || (ss < 0) || (ss > 59)) {
															return 0;
														}
														i_val += ss.length;
													} else {
														if (token == "a") {
															if (val.substring(i_val, i_val + 2).toLowerCase() == "am") {
																ampm = "AM";
															} else {
																if (val.substring(i_val, i_val + 2).toLowerCase() == "pm") {
																	ampm = "PM";
																} else {
																	return 0;
																}
															}
															i_val += 2;
														} else {
															if (val.substring(i_val, i_val + token.length) != token) {
																return 0;
															} else {
																i_val += token.length;
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		// If there are any trailing characters left in the value, it doesn't match
		if (i_val != val.length) {
			return 0;
		}
		// Is date valid for month?
		if (month == 2) {
		// Check for leap year
			if (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)) { // leap year
				if (date > 29) {
					return 0;
				}
			} else {
				if (date > 28) {
					return 0;
				}
			}
		}
		if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
			if (date > 30) {
				return 0;
			}
		}
	// Correct hours value
		if (hh < 12 && ampm == "PM") {
			hh = hh - 0 + 12;
		} else {
			if (hh > 11 && ampm == "AM") {
				hh -= 12;
			}
		}
		var newdate = new Date(year, month - 1, date, hh, mm, ss);
		return newdate.getTime();
	};
	
	// false: it's not future; true: it's future
	this.verifyFutureDate = function (str, format) {
		var dt = this.stringToDate(str, format);
		if (dt === 0) {
			return false;
		}
		return (dt > (new Date()).getTime()) ? true : false;
	};
	
	// false: it's not past; true: it's past
	this.verifyPastDate = function (str, format) {
		var dt = this.stringToDate(str, format);
		if (dt === 0) {
			return false;
		}
		var nd = new Date();
		nd.setHours(0);
		nd.setMinutes(0);
		nd.setSeconds(0);
		nd.setMilliseconds(0);
		var td = nd.getTime();
		return (dt < td) ? true : false;
	};
	
	// get the value of a cookie
	this.getCookie = function (ckName) {
		var allcookies = document.cookie;
		var cookie_pos = allcookies.indexOf(ckName);
		var value = "";
		if (cookie_pos != -1) {
			cookie_pos += ckName.length + 1;
			var cookie_end = allcookies.indexOf(";", cookie_pos);
			if (cookie_end == -1) {
				cookie_end = allcookies.length;
			}
			value = unescape(allcookies.substring(cookie_pos, cookie_end));
		}
		return value;
	};
	
	// verify the element exists
	this.exist = function (id) {
		var el = document.getElementById(id);
		if (el === null) {
			el = document.getElementsByName(id)[0];
		}
		return (el !== null) && (typeof el !== "undefined");
	};
	
	// verify if the object is an Array
	this.isArray = function (arr) {
		//  && !(arr.propertyIsEnumerable("length"))
		if (arr && typeof arr === "object" && typeof arr.length === "number") {
			return true;
		}
		return false;
	};
	
	// verify if the object is a string
	this.isString = function(str){
		if (str && typeof str === "string" && typeof str.length === "number" && !(str.propertyIsEnumerable("length"))) {
			return true;
		}
		return false;
	};
	
	// verify if the object is valid
	this.isValidObj = function(obj){
		return (obj && typeof obj !== "undefiend");
	};
	
	this.nextDate = function(dt) {
		return new Date(dt.getFullYear(), dt.getMonth(), dt.getDate() + 1);
	};
}

// -------------------------------------------------------------------------------------
// Gui class
function Gui() {
	// verify if the element exists
	this.exist = function (flag) {
		var e = document.getElementById(flag);
		if (e === null) {
			e = document.getElementsByName(flag)[0];
		}
		return (e !== null && typeof e != "undefined") ? true : false;
	};
	
	// display an element
	this.display = function (comptId) {
		if (this.exist(comptId)) {
			$(comptId).style.display = "block";
		}
	};
	
	// hide an element
	this.hide = function (comptId) {
		if (this.exist(comptId)) {
			$(comptId).style.display = "none";
		}
	};
	
	// show message on UI
	this.showMsg = function (id, text) {
		var el = $(id);
		el.style.display = "inline";
		el.innerHTML = text;
	};
	
	// show message on UI
	this.hideMsg = function (id) {
		var el = $(id);
		el.style.display = "none";
		el.innerHTML = "";
	};
	
	// enable an element
	this.enable = function (id) {
		if (id !== null) {
			$(id).disabled = false;
			$(id).style.color = "#ffffff";
		}
	};
	
	// disable an element
	this.disable = function (id) {
		if (id !== null) {
			$(id).disabled = true;
			$(id).style.color = "#BFBFBF";
		}
	};
	
	// make the row looks different from others when mouse is over it
	this.lighten = function (id) {
		$(id).style.background = "#DEE6EE";
	};
	
	// make the row looks same as others when mouse is out
	this.goOut = function (id) {
		$(id).style.background = "white";
	};
	
	// show progress element before data is loaded to the page
	// block: where to show the progress
	// type: 0- big; 1 - small
	this.showProgressIn = function (block, type) {
		if (block === null || typeof block == "undefined") {
			return;
		}
		if (typeof type == "undefined" || (type !== 0 && type != 1)) {
			type = 0;
		}
		return block.innerHTML = (type === 0) ? "<img class='big-loading' src='res/images/big_loading.gif'/>" : "<img src='res/images/small_loading.gif'/>";
	};
	
	// calculate the current window width //
	this.pageWidth = function () {
		return window.innerWidth != null ? window.innerWidth : document.documentElement && document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null;
	};

	// calculate the current window height //
	this.pageHeight = function () {
		return window.innerHeight != null ? window.innerHeight : document.documentElement && document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body != null ? document.body.clientHeight : null;
	};

	// calculate the current window vertical offset //
	this.topPosition = function () {
		return typeof window.pageYOffset != "undefined" ? window.pageYOffset : document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ? document.body.scrollTop : 0;
	};

	// calculate the position starting at the left of the window //
	this.leftPosition = function () {
		return typeof window.pageXOffset !== "undefined" ? window.pageXOffset : document.documentElement && document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ? document.body.scrollLeft : 0;
	};
	
	// remove the specific node. the removeChild of some elements may not supported in IE
	this.removeNode = function (node) {
		if(node === null || typeof node === "undefined") {
			window.alert("invalid parameter");
			return;
		}
		// if the browser is IE
		if(this.typeOfBrowser() == "IE") {
			node.removeNode(true);
		}
		else {
			parent = node.parentNode;
			parent.removeChild(node);
		}
	};
	
	// check what kind of the browser, IE/FF/OP/SF/CR
	this.typeOfBrowser = function () {
        var ua = navigator.userAgent.toLowerCase();
        var browser = null;
        try {
	        if (window.ActiveXObject) {
	            if(ua.match(/msie ([\d.]+)/)[1]) browser = "IE";
	        }
	        else if (document.getBoxObjectFor) {
	            if(ua.match(/firefox\/([\d.]+)/)[1]) browser = "FF";
	        }
	        else if (window.MessageEvent && !document.getBoxObjectFor) {
	            if(ua.match(/chrome\/([\d.]+)/)[1]) browser = "CR";
	        }
	        else if (window.opera) {
	            if(ua.match(/opera.([\d.]+)/)[1]) browser = "OP";
	        }
	        else if (window.openDatabase) {
	            if(ua.match(/version\/([\d.]+)/)[1]) browser = "SF";
	        }
        }
        catch (e) {
        
        }
        return browser;
	};
	
	this.cloneNode = function(ele, options) {
		if(typeof dwr === "undefiend" || typeof dwr.util === "undefiend"){
			window.alert("import dwr/util.js firstly");
			return;
		}
		ele = dwr.util._getElementById(ele, "cloneNode()");
	   	if (ele == null) return null;
	   	if (options == null) options = {};
	  	var clone = ele.cloneNode(true);
	   	if (options.idPrefix || options.idSuffix) {
		       dwr.util._updateIds(clone, options);
	   	}
	   	else {
	       dwr.util._removeIds(clone);
	   	}
	  	clone.style.display = "block";
	   	return clone;
	};
	
	this.getParentNode = function(eleId){
		if(typeof dwr === "undefiend" || typeof dwr.util === "undefiend"){
			window.alert("import dwr/util.js firstly");
			return;
		}
		if(eleId == null) {
			window.alert("null element");
		}
		else {
			window.alert(dwr.util._getElementById(eleId));
			return dwr.util._getElementById(eleId).parentNode;
		}
	};
	
}

// ---------------------------------------------------------
function UploadImage() {
	this.allowExts = ".jpg,.jpeg, .gif";
	this.allowImgFileSize = 2066432; // 2M
	this.allowImgWidth = 0;
	this.allowImgHeight = 0;
	this.imgFileSize = 0;
	this.imgWidth = 0;
	this.imgHeight = 0;
	this.fileExt = "";
	this.errMsg = "";
	this.isImg = false;
	this.imgObj = new Image();
}
UploadImage.prototype.setPath = function (path) {
	this.imgObj.src = path;
};
UploadImage.prototype.setMaxSize = function (size) {
	this.allowImgFileSize = size;
};
UploadImage.prototype.isValid = function () {
	if (this.imgObj.src === null || this.imgObj.src == "") {
		return false;
	}
	var ext = this.imgObj.src.lastIndexOf(".");
	if (ext == -1) {
		return false;
	}
	ext = this.imgObj.src.substr(ext).toLowerCase();
	if (this.allowExts.indexOf(ext) == -1) {
		return false;
	}
	if (this.imgObj.fileSize == 0 || this.imgObj.fileSize > this.allowImgFileSize) {
		return false;
	}
	return true;
};

